package com.sinodata.bsm.center.expression;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.PropertyBean;
import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.cache.PropertyCache;
import com.sinodata.bsm.center.service.performance.PropValueService;
import com.sinodata.bsm.center.service.performance.RealTimeService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.common.vo.Property;
import com.sinodata.bsm.common.vo.PropertyValue;
import com.sinodata.bsm.common.vo.Res;

public class ChartCalctor {
    private BatchCalctor batchCalctor;

    private PropValueService propService;

    private PropertyCache propertyCache;

    public ChartCalctor(BatchCalctor bc) {
        batchCalctor = bc;
        propService = SpringContextHolder.getBean(PropValueService.class);
        propertyCache = SpringContextHolder.getBean(PropertyCache.class);
    }

    public void calcChart(Element element) {
        String chartName = element.element("cdata").attributeValue("name");
        if (chartName.equalsIgnoreCase("spline")) {
            calcLineChart(element);
        } else if (chartName.equalsIgnoreCase("fchart")) {
            calcFchart(element);
        }
    }

    public void calcLineChart(Element element) {
        String[] propArry = element.element("cdata").element("props").getTextTrim().split(",");
        String resid = batchCalctor.varsMap.get("$resid").toString();
        for (int i = 0; i < propArry.length; i++) {
            String pi = batchCalctor.varsMap.get(propArry[i]).toString();
            if (pi != null) {
                propArry[i] = pi;
            }

        }
        Long resId = Long.parseLong(resid);
        List<Res> ress = Functions.childByProp(resId, Long.parseLong(propArry[0]));
        if (ress.size() == 0) {
            return;
        }
        Res res = ress.get(0);
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        Calendar now = Calendar.getInstance();
        String startDate = sf.format(now.getTime()) + "000000";
        int[] storeOrder = new int[propArry.length];
        Property[] propArray = new Property[propArry.length];
        for (int i = 0; i < propArry.length; i++) {
            Property p = propertyCache.get(Long.parseLong(propArry[i]));
            int ii = p.getStore();
            storeOrder[i] = ii;
            propArray[i] = p;
        }
        //--------------series--------------
        Element series = element.element("cdata").element("series");
        for (int i = 0; i < propArray.length; i++) {
            Element lineSeries = series.addElement("lineSeries");
            lineSeries.addAttribute("yField", propArray[i].getName());
            lineSeries.addAttribute("displayName", res.getName() + " " + propArray[i].getName());
        }

        //--------------datas-----------------
        List<PropertyValue> list = propService.getPropValues(Long.parseLong(resid), storeOrder, startDate, "", "1");
        Element datas = element.element("cdata").element("datas");
        for (PropertyValue pv : list) {
            Element data = datas.addElement("data");
            data.addAttribute("date", pv.getTime().toString());
            for (int i = 0; i < propArray.length; i++) {
                data.addAttribute(propArray[i].getName(), pv.getValues()[i]);
            }
        }

    }

    /*
     *     <element type="psd.widgets.primer.FChart" id="layer0_1_5" x="48" y="71" w="276" h="205">
    <p name="color" type="color"></p>
    <p name="text" type="string">磁盘</p>
    <p name="fontSize" type="uint">12</p>
    <p name="value" type="string"></p>
    <p name="dataUnit" type="string"></p>
    <p name="FChart" text="图表" type="fchart"/>
    <cdata>
      <chartType>MSColumn3D</chartType>
      <ress>$资源名1,$资源名2,$资源名3</ress>
      <props>$指标1,$指标2,$指标3</props>
      <chart caption="磁盘" bgAlpha="0,0" showValues="0" legendBgAlpha="0" canvasbgAlpha="0" canvasBorderAlpha="0" outCnvBaseFontSize="12" outCnvBaseFontColor="0xffffff">
        <categories>
          <category label="$资源名1"/>
          <category label="$资源名2"/>
          <category label="$资源名3"/>
        </categories>
        <dataset seriesName="$指标1">
          <set value="0"/>
          <set value="0"/>
          <set value="0"/>
        </dataset>
        <dataset seriesName="$指标2">
          <set value="0"/>
          <set value="0"/>
          <set value="0"/>
        </dataset>
        <dataset seriesName="$指标3">
          <set value="0"/>
          <set value="0"/>
          <set value="0"/>
        </dataset>
      </chart>
    </cdata>
    </element>
     */
    public void calcFchart(Element element) {
        String resstr = element.element("cdata").element("ress").getTextTrim();
        String[] props = element.element("cdata").element("props").getTextTrim().split(",");
        //如果是资源
        Object varObj = batchCalctor.varsMap.get(resstr);
        if (varObj != null) {
            if (varObj instanceof ResBean[]) {
                ResBean[] resBeans = (ResBean[]) varObj;
                List<ResBean> list = new ArrayList<ResBean>();
                for (int i = 0; i < resBeans.length; i++) {
                    list.add(resBeans[i]);
                }
                varObj = list;
            }
            if (varObj instanceof List) {
                List<ResBean> resBeans = (List<ResBean>) varObj;
                Element chartEle = element.element("cdata").element("chart");
                //删除categories
                chartEle.remove(chartEle.element("categories"));
                addCategory(element.element("cdata"), resBeans);
                //删除所有dataset
                Element ds = null;
                while ((ds = chartEle.element("dataset")) != null) {
                    chartEle.remove(ds);
                }
                for (int i = 0; i < props.length; i++) {
                    String propK = props[i];
                    long propId = Long.parseLong(batchCalctor.varsMap.get(propK) + "");
                    addDataSet(element.element("cdata"), resBeans, propId);
                }
            }
        }

    }

    private void addCategory(Element cdata, List<ResBean> reses) {
        Element categories = cdata.element("chart").addElement("categories");
        for (ResBean res : reses) {
            Element category = categories.addElement("category");
            category.addAttribute("label", res.res().getName());
        }
    }

    private void addDataSet(Element cdata, List<ResBean> reses, Long propId) {
        Element dataset = cdata.element("chart").addElement("dataset");
        Property pb = PropertyBean.get(propId).property();
        dataset.addAttribute("seriesName", pb.getName());
        for (ResBean child : reses) {
            Element set = dataset.addElement("set");
            set.addAttribute("value", "0");
            Object propVal = Functions.getPropertyValue(child.res().getId(), propId);
            if (propVal != null) {
                set.addAttribute("value", Functions.getPropertyValue(child.res().getId(), propId).toString());
            }

        }
    }
}
